home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / akputil7.zoo / ls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-16  |  6.3 KB  |  298 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <osbind.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6.  
  7. #ifdef __GNUC__
  8. /* minimal stuff */
  9.  
  10. #include <minimal.h>
  11. #include <stdarg.h>
  12.  
  13. int printf(const char *fmt,...)
  14. {
  15.     va_list args;
  16.     char buf[128];
  17.     va_start(args,fmt);
  18.     vsprintf(buf,fmt,args);
  19.     Cconws(buf);
  20.     return 0;
  21. }
  22.  
  23. #undef putchar
  24. #define putchar(c) Cconout(c)
  25. #endif
  26.  
  27. #define TRUE 1
  28. #define FALSE 0
  29.  
  30. #define DRV_CHAR ':'
  31. #define PATH_CHAR '\\'
  32.  
  33. extern char *syserr(long);
  34.  
  35. struct _dta *dtas = 0;
  36. int nfiles = 0;
  37. int nalloc = 0;
  38.  
  39. int lflag = 0, fflag = 0, aflag = 0, rflag = 0, tflag = 0;
  40.  
  41. int cmpname(const struct _dta *a, const struct _dta *b)
  42. {
  43.     return strcmp(a->dta_name,b->dta_name);
  44. }
  45.  
  46. int cmptime(const struct _dta *a, const struct _dta *b)
  47. {
  48.     unsigned long datime1, datime2;
  49.     datime1 = ((unsigned long)a->dta_date) << 16 |
  50.     (unsigned long)a->dta_time;
  51.     datime2 = ((unsigned long)b->dta_date) << 16 |
  52.     (unsigned long)b->dta_time;
  53.     if (datime1 > datime2) return -1;
  54.     else if (datime1 == datime2) return 0;
  55.     else return 1;
  56. }
  57.  
  58. void
  59. add_file(struct _dta *dta)
  60. {
  61.     if (dtas == 0) {
  62.     dtas = malloc(10 * sizeof(struct _dta));
  63.     nalloc = 10;
  64.     nfiles = 0;
  65.     }
  66.     else if (nalloc == nfiles) {
  67.     nalloc += 10;
  68.     if ((dtas = realloc(dtas,nalloc * sizeof(struct _dta))) == NULL) {
  69.         printf("Out of memory\r\n");
  70.         Pterm(1);
  71.     }
  72.     }
  73.     dtas[nfiles] = *dta;
  74.     nfiles++;
  75. }
  76.  
  77. void
  78. downcase(char *s)
  79. {
  80.     while (*s) {
  81.     if (isupper(*s)) *s = tolower(*s);
  82.     s++;
  83.     }
  84. }
  85.  
  86. char *suffixes[] = { ".ttp", ".prg", ".tos", ".app" };
  87. #define NSUFFIXES (sizeof(suffixes) / sizeof(char *))
  88.  
  89. inline int
  90. isexec(char *s)
  91. {
  92.     int i;
  93.     for (i = NSUFFIXES; --i >= 0; ) {
  94.     if (strstr(s,suffixes[i])) return 1;
  95.     }
  96.     return 0;
  97. }
  98.  
  99. void
  100. do_dir(const char *name) {
  101.     char buf[128];        /* requested path ends up here */
  102.     char *temp;
  103.     struct _dta *odta = (struct _dta *)Fgetdta();
  104.     struct _dta dta;
  105.     char *p;
  106.     int i, j, k, n, nrows;
  107.     int dflag;
  108.     long e;
  109.     struct _dta *s;
  110.     int (*cmpfn)(const void *,const void *);
  111.  
  112.     strcpy(buf,name);
  113.     temp = buf;
  114.     while (*temp) temp++;
  115.  
  116.     /* if arg ends with a backslash, slash, or colon, add "*.*" to it */
  117.     if (*(temp-1) == DRV_CHAR || *(temp-1) == PATH_CHAR) {
  118.     strcpy(temp,"*.*");
  119.     dflag=TRUE;    /* dflag says this is a directory */
  120.     }
  121.     else dflag = FALSE;
  122.  
  123.     /* if the name has no wildcards, find the file. */
  124.     /* if it turns out to be a directory, add "\*.*" to it */
  125.  
  126.     (void)Fsetdta(&dta);
  127.     if ((strchr(buf,'*') == NULL) && (strchr(buf,'?') == NULL)) {
  128.     /* no wildcards */
  129.     if ((e = Fsfirst(buf,-1)) < 0) {
  130.         printf("%s: %s\r\n",buf,syserr(e));
  131.         goto reallydone;
  132.     }
  133.     else {
  134.         /* found the file: is it a directory? */
  135.         if (dta.dta_attribute & 0x10) {
  136.         /* directory: add \*.* to it */
  137.         /* \\ below should be PATH_CHAR */
  138.         strcpy(temp,"\\*.*");
  139.         temp++;
  140.         }
  141.         else {
  142.         /* no wildcards, file exists, not a directory: unique */
  143.         downcase(dta.dta_name);
  144.         add_file(&dta);
  145.         goto gotfiles;
  146.         }
  147.     }
  148.     }
  149.  
  150.     /* do the Fsfirst again because buf may have changed */
  151.     if ((e = Fsfirst(buf,-1)) < 0) {
  152.     if (dflag) printf("no files\r\n");
  153.     else printf("%s: %s\r\n",buf,syserr(e));
  154.     goto reallydone;
  155.     }
  156.     n = 0;
  157.  
  158.     do {
  159.     /* add the file to the list of files */
  160.     /* add all files if aflag, else skip those with leading dots */
  161.     if (aflag || *(dta.dta_name) != '.') {
  162.         downcase(dta.dta_name);
  163.         add_file(&dta);
  164.     }
  165.     } while (Fsnext() == 0);
  166.  
  167.     if (nfiles == 0) {
  168.     printf("no files\r\n");
  169.     goto reallydone;
  170.     }
  171.  
  172.     /* I hate this messy cast... */
  173.     cmpfn = (tflag ? (int (*)(const void *,const void *))cmptime
  174.            : (int (*)(const void *,const void *))cmpname);
  175.     qsort(dtas,(size_t)nfiles,sizeof(struct _dta),cmpfn);
  176.  
  177. gotfiles:
  178.     if (lflag) {
  179.     for (i = 0, s = dtas; i < nfiles; s++, i++) {
  180.         printf("%02x %02d/%02d/%02d %02d:%02d:%02d %8ld %s%c\r\n",
  181.         s->dta_attribute,
  182.         (s->dta_date >> 9) + 80,
  183.         (s->dta_date >> 5) & 0xf,
  184.         (s->dta_date) & 0x1f,
  185.  
  186.         (s->dta_time >> 11),
  187.         (s->dta_time >> 5) & 0x3f,
  188.         (s->dta_time & 0x1f),
  189.         s->dta_size,
  190.         s->dta_name,
  191.         (!fflag ? ' ' : ((s->dta_attribute & 0x10 ? '\\' : 
  192.                    (isexec(s->dta_name) ? '*' : ' ')))));
  193.     }
  194.     }
  195.     else {
  196.  
  197. #define NCOLS 5
  198.  
  199.     /* output in 5-column format */
  200.     nrows = (nfiles + (NCOLS-1)) / NCOLS;
  201.     for (i = 0; i < nrows; i++) {
  202.         s = &dtas[i];
  203.         for (j = 0; j < NCOLS; j++, s += nrows) {
  204.         if (s >= &dtas[nfiles]) {
  205.             printf("\r\n");
  206.             break;
  207.         }
  208.         printf("%s",s->dta_name);
  209.         k = strlen(s->dta_name);
  210.         if (fflag) {
  211.             if (s->dta_attribute & 0x10) {
  212.             putchar('\\');
  213.             k++;
  214.             }
  215.             else if (isexec(s->dta_name)) {
  216.             putchar('*');
  217.             k++;
  218.             }
  219.         }
  220.         /* don't output tab(s) after the last name on a line */
  221.         if (j < (NCOLS-1)) {
  222.             if (k<8) putchar('\t');
  223.             putchar('\t');
  224.         }
  225.         else printf("\r\n");
  226.         }
  227.     }
  228.     }
  229.  
  230.     if (dtas) {
  231.     free(dtas);
  232.     dtas = NULL;
  233.     nalloc = 0;
  234.     nfiles = 0;
  235.     }
  236.     if (rflag) {
  237.     /* Do another Fsfirst/Fsnext pass for directories. */
  238.     /* Remember, buf has the Fsfirst target. */
  239.     /* Set temp just past the last PATH_CHAR or DIR_CHAR. */
  240.  
  241.     if ((temp = strrchr(buf,PATH_CHAR)) == NULL) temp = buf;
  242.     else temp++;
  243.  
  244.     if ((p = strrchr(temp,DRV_CHAR)) != NULL) temp = p+1;
  245.  
  246.     if (Fsfirst(buf,-1) < 0) goto reallydone;
  247.     do {
  248.         if (dta.dta_attribute & 0x10 && *dta.dta_name != '.') {
  249.         strcpy(temp,dta.dta_name);
  250.         downcase(buf);
  251.         printf("\r\n%s:\r\n",buf);
  252.         do_dir(buf);
  253.         }
  254.     } while (!Fsnext());
  255.     }
  256.             
  257. reallydone:
  258.     (void)Fsetdta(odta);
  259. }
  260.  
  261. int
  262. main(int argc,char *argv[])
  263. {
  264.     char *p;
  265.     --argc, ++argv;
  266.     while (*argv && **argv == '-') {
  267.         p = &argv[0][1];
  268.         while (*p) {
  269.         switch (*p) {
  270.         case 'l': lflag = 1; break;
  271.         case 'F': fflag = 1; break;
  272.         case 'a': aflag = 1; break;
  273.         case 'R': rflag = 1; break;
  274.         case 't': tflag = 1; break;
  275.         default:
  276.             printf("Unknown option: %s\r\n",*p);
  277.             printf("Usage: ls [-aFlRt] [files ...]\r\n");
  278.             exit(1);
  279.         }
  280.         p++;
  281.     }
  282.     argc--, argv++;
  283.     }
  284.  
  285.     if (!argc) {
  286.     argc = 1;
  287.     *argv = "*.*";
  288.     }
  289.  
  290.     while (argc) {
  291.     do_dir(*argv);
  292.     argv++, argc--;
  293.     if (argc) printf("\r\n");
  294.     }
  295.     exit(0);
  296. }
  297.  
  298.